#include "ImgDirLoader.h"
#include <QtCore/QDir>
#include <QtGui/QImageReader>
#include <QtCore/QStringList>
#include <QtCore/QByteArray>
#include <QtCore/QDir>
#include <QtCore/QtConcurrentMap>
#include <QtCore/QDebug>
#include <boost/bind.hpp>
#include <assert.h>
#include "Utility.h"

ImgDirLoader::ImgDirLoader(const QString& dirPath,QObject *parent)
	: QObject(parent),_dirPath(dirPath),_loadingFinished(false),_lastAccessTm(QDateTime::currentDateTime())
{
}

ImgDirLoader::~ImgDirLoader()
{
	if (_loadingFuture.isRunning()){
		stopLoading();
		_loadingFuture.waitForFinished();
	}
}

const QImage& ImgDirLoader::image(const QString& filePath) const{
	if (_loadingFinished || !_loadingFuture.isRunning()){
		return _imageMap[filePath];
	}else{
		QMutexLocker l(&_imgMapMutex);
		return _imageMap[filePath];
	}
}

void ImgDirLoader::loadImageFromFile(const QString&  file){
	QImageReader imgReader(file);
	imgReader.setQuality(10);
	QSize imgSize(imgReader.size());
	if (imgSize.isValid()){
		if (imgSize.width()>70 || imgSize.height()>70){
			imgSize.scale(70,70,Qt::KeepAspectRatio);
			imgReader.setScaledSize(imgSize);
		}
	}
	QImage img=imgReader.read();
	if (!img.isNull()){
		{
		QMutexLocker l(&_imgMapMutex);
		_imageMap[file]=img;
		}
		qDebug()<<"Emit imageLoaded("<<file<<").\n";
		emit imageLoaded(file);
	}else{
		{
		QMutexLocker l(&_imgMapMutex);
		_imageMap[file]=QImage(":/imgs/failed.PNG");
		}
		qDebug()<<"Fail to load image "<<file<<":"<<imgReader.errorString ()<<"\n";
	}
}

QStringList ImgDirLoader::getResidualImgFiles(const QStringList& imgFiles) const{
	QStringList ret;
	foreach(const QString& imgFile,imgFiles){
		{
			QMutexLocker l(&_imgMapMutex);
			if (_imageMap[imgFile].isNull()){
				ret<<imgFile;
			}
		}
	}
	return ret;
}

void ImgDirLoader::startLoad(const QStringList& imgFiles){
	_lastAccessTm=QDateTime::currentDateTime();
	if (_loadingFinished || _loadingFuture.isRunning()){
		return ;
	}

	_residualImgFiles=getResidualImgFiles(imgFiles);
	if (_residualImgFiles.isEmpty()){
		_loadingFinished=true;
		return ;
	}

	qDebug()<<"Loading "<<_residualImgFiles.size()<<" image files ...\n";
	_loadingFuture=QtConcurrent::map(_residualImgFiles,
			boost::bind(&ImgDirLoader::loadImageFromFile,this,_1)
			);
}

void ImgDirLoader::stopLoading(){
	if (_loadingFuture.isRunning()){
		_loadingFuture.cancel();
		//if (!_dirPath.isNull())
		//	qDebug()<<"Cancel loading "<<_dirPath<<"\\ files ...\n";
	}
}


QDateTime ImgDirLoader::lastAccessTime() const{
	return _lastAccessTm;
}

void ImgDirLoader::clearLoadedImages(){
	QMutexLocker l(&_imgMapMutex);
	_imageMap.clear();
}
